#include "simulationrunner.h"

#include <netrunner.h>
#include <netrunnable.h>
#include <wfnet.h>

#include <QtCore/QTimer>

using namespace swp;
using namespace wfnet;

SimulationRunner* simulationRunner = 0;

SimulationRunner* SimulationRunner::getInstance()
{
    if (simulationRunner == 0)
    {
        simulationRunner = new SimulationRunner();
    }

    return simulationRunner;
}

void SimulationRunner::destroy()
{
    delete simulationRunner;
    simulationRunner = 0;
}

void SimulationRunner::simulate(wfnet::WfNet* net, int repetitions,
    int timeout)
{
    if (m_state == Idle)
    {
        m_state = Running;

        if (m_net != net)
        {
            if (m_net != 0)
            {
                disconnect(m_net, SIGNAL(finished()),
                    this, SLOT(emitFinished()));
            }
            connect(net, SIGNAL(finished()), this, SLOT(emitFinished()));
        }

        m_net = net;

        emit simulationStarted();

        m_timeoutTimer->start(timeout);

        net->run(repetitions);
    }
}

SimulationRunner::SimulationRunner() : QObject(), m_net(0), m_state(Idle),
    m_timeoutTimer(new QTimer(this))
{
    connect(m_timeoutTimer, SIGNAL(timeout()), this, SLOT(interrupt()),
        Qt::QueuedConnection);
}

SimulationRunner::~SimulationRunner()
{

}

// public slots
void SimulationRunner::nextStep()
{

}

void SimulationRunner::previousStep()
{

}

void SimulationRunner::pause()
{
    if (m_state == Running)
    {
        m_state = Paused;

        m_net->pause();

        emit simulationPaused();
    }
}

void SimulationRunner::continueSimulation()
{
    if (m_state == Paused)
    {
        m_state = Running;

        //m_net->run();

        emit simulationContinued();
    }
}

void SimulationRunner::stop()
{
    if (m_state == Running)
    {
        m_state = Idle;

        m_net->stop();

        emit simulationFinished(true);
    }
}

void SimulationRunner::interrupt()
{
    m_timeoutTimer->stop();

    if (m_state == Running)
    {
        m_state = Idle;

        m_net->stop();

        emit simulationFinished(true);
    }
}

// private slots
void SimulationRunner::emitFinished()
{
    m_state = Idle;

    emit simulationFinished(false);
}

